package com.songyang.blog.controller;


import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.songyang.blog.common.lang.Result;
import com.songyang.blog.config.RabbitMqConfig;
import com.songyang.blog.entity.*;
import com.songyang.blog.search.mq.PostMqIndexMessage;
import com.songyang.blog.util.ValidationUtil;
import com.songyang.blog.vo.CommentVO;
import com.songyang.blog.vo.PostVO;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Date;

@Controller
public class PostController extends BaseController {
    @GetMapping("/category/{id:\\d*}")
    public String category(@PathVariable(name = "id") Long id) {
        request.setAttribute("currentCategoryId", id);
        return "post/category";
    }

    @GetMapping("/post/{id:\\d*}")
    public String detail(@PathVariable(name = "id") Long id) {
        PostVO vo = postService.selectOnePost(new QueryWrapper<Post>().eq("p.id", id));

        Assert.notNull(vo, "文章已被删除");
        //未了实现每刷新一次、访问一次访问量就加1，调用这个方法
        postService.putVIewCount(vo);
        //1 分页 ，2 文章 3 用户第 4 排序
        IPage<CommentVO> result = commentService.paging(getPage(), vo.getId(), null, "created");//获取评论列表
        request.setAttribute("currentCategoryId", vo.getCategoryId());
        request.setAttribute("post", vo);

        User user = new User();
        if (getProfile() != null) {
            user.setId(getProfileId());
            request.setAttribute("user", user);
        } else user.setId(0L);

        request.setAttribute("pageData", result);
        return "/post/detail";
    }

    @ResponseBody
    @PostMapping("/collection/find")
    public Result CollectionFind(Long pid) {//判断当前用户是否收藏该文章！
        int count = collectionService.count(new QueryWrapper<UserCollection>()
                .eq("user_id", getProfileId())
                .eq("post_id", pid)
        );
        return Result.success(MapUtil.of("collection", count > 0));//这里大于0就是true，小于就是false
    }

    @ResponseBody
    @PostMapping("/collection/add")
    public Result CollectionAdd(Long pid) {//给当前用户收藏一篇文章
        Post post = postService.getById(pid);
        Assert.isTrue(post != null, "该帖子已被删除");
        int count = collectionService.count(new QueryWrapper<UserCollection>()
                .eq("user_id", getProfileId())
                .eq("post_id", pid)
        );
        if (count > 0) {
            return Result.fail("该帖子已经被你收藏了!");
        }
        UserCollection userCollection = new UserCollection();//创建一个对象
        userCollection.setUserId(getProfileId());//给这个对象设置用户的id
        userCollection.setPostId(pid);//设置帖子的id
        userCollection.setCreated(new Date());//设置创建时间
        userCollection.setPostUserId(post.getUserId());//作者id
        userCollection.setModified(new Date());
        collectionService.save(userCollection);//更新一下数据库，把该条记录写入到数据库当中
        return Result.success();
    }

    @ResponseBody
    @PostMapping("/collection/remove")
    public Result CollectionRemove(Long pid) {//给当前文章的当前用户取消对当前 的文章的收藏
        Post post = postService.getById(pid);
        Assert.isTrue(post != null, "该帖子已被删除");
        int count = collectionService.count(new QueryWrapper<UserCollection>()
                .eq("user_id", getProfileId())
                .eq("post_id", pid)
        );
        if (count == 0) {
            return Result.fail("你已经对该帖子取消收藏了");
        }
        collectionService.remove(new QueryWrapper<UserCollection>()
                .eq("user_id", getProfileId())
                .eq("post_id", pid)
        );//删除该条记录，取消收藏

        return Result.success();
    }

    @GetMapping("/post/edit")
    public String edit() {
        String id = request.getParameter("id");//如果可以获得一个id，那么说明此次操作为编辑而不是发表新帖
        if (!StrUtil.isEmpty(id)) {
            Post post = postService.getById(id);
            Assert.isTrue(post != null, "该帖子已被删除");
            Assert.isTrue(post.getUserId() == getProfileId(), "你没有权限操作!");
            request.setAttribute("post", post);
        }
        request.setAttribute("categories", categoryService.list());//获取所有的分类信息
        return "/post/edit";
    }

    @ResponseBody
    @GetMapping("/post/delete")//删除帖子
    public Result delete(Long id) {
        Post post = postService.getById(id);
        Assert.isTrue(post != null, "该帖子已被删除");
        Assert.isTrue(post.getUserId().longValue() == getProfileId().longValue(), "你没有权限操作!");
        postService.removeById(id);
        amqpTemplate.convertAndSend(RabbitMqConfig.ex_exchange, RabbitMqConfig.es_bind_key
                , new PostMqIndexMessage(post.getId(), PostMqIndexMessage.REMOVE));
        return Result.success().action("/user/index");

    }

    @GetMapping("/hello")
    public String hello() {
        return "/hello";
    }

    @ResponseBody
    @PostMapping("/post/submit")
    public Result postSubmit(Post post) {
        ValidationUtil.ValidResult validResult = ValidationUtil.validateBean(post);
        if (validResult.hasErrors()) {
            return Result.fail(validResult.getErrors());
        }
        if (post.getId() == null) {//id为空说明这次是新增一个博客
            post.setUserId(getProfileId());
            post.setModified(new Date());
            post.setCreated(new Date());
            post.setCommentCount(0);
            post.setEditMode(null);
            post.setLevel(0);
            post.setRecommend(false);
            post.setViewCount(0);
            post.setVoteDown(0);
            post.setVoteUp(0);
            postService.save(post);
            //通知mq去更新es的索引
            amqpTemplate.convertAndSend(RabbitMqConfig.ex_exchange, RabbitMqConfig.es_bind_key
                    , new PostMqIndexMessage(post.getId(), PostMqIndexMessage.CREATE_OR_UPDATE));
            return Result.success("添加博客成功！").action("/post/" + post.getId());//成功之后跳转这个博客的详情页！
        } else {//如果有id很明显是修改编辑的操作
            Post tempPost = postService.getById(post.getId());
            org.springframework.util.Assert.isTrue(
                    tempPost.getUserId().longValue() == getProfileId().longValue()
                    , "无权限编辑此文章！");
            tempPost.setTitle(post.getTitle());
            tempPost.setContent(post.getContent());
            tempPost.setCategoryId(post.getCategoryId());
            postService.updateById(tempPost);
            //通知mq去更新es的索引
            amqpTemplate.convertAndSend(RabbitMqConfig.ex_exchange, RabbitMqConfig.es_bind_key
                    , new PostMqIndexMessage(post.getId(), PostMqIndexMessage.CREATE_OR_UPDATE));
            return Result.success("编辑成功!").action("/post/" + post.getId());//成功之后跳转这个博客的详情页！
        }
    }

    @PostMapping("/post/reply")
    @ResponseBody
    public Result comment(Long jid, String content) {
        String comKey = "comment:user:" + getProfileId() + "post:" + jid;
        Object value = redisUtil.get(comKey);
        if (value == null) {
            redisUtil.set(comKey, "1");
            redisUtil.expire(comKey, 50);
            Post post = postService.getById(jid);
            Assert.notNull(post, "找不到对应文章");
            Assert.hasLength(content, "评论内容不能为空");
            Comment comment = new Comment();
            comment.setPostId(jid);
            comment.setContent(content);
            comment.setUserId(getProfileId());
            comment.setCreated(new Date());
            comment.setModified(new Date());
            comment.setLevel(0);
            comment.setVoteDown(0);
            comment.setVoteUp(0);
            commentService.save(comment);//保存评论
            post.setCommentCount(post.getCommentCount() + 1);
            postService.updateById(post);//评论数加一

            //本周热议数量加一
            postService.incrCommentAndUnionForWeekRank(post.getId(), true);

            //通知作者有人评论了你的文章
            if (comment.getUserId() != post.getUserId()) {//如果是作者自己评论的自己,就不需要提示
                UserMessage message = new UserMessage();
                message.setPostId(jid);
                message.setCommentId(comment.getId());
                message.setFromUserId(getProfileId());
                message.setToUserId(post.getUserId());//通知作者，也就是文章的发表者
                message.setType(1);//0是系统消息，1是其他消息
                message.setContent(content);
                message.setCreated(new Date());
                message.setStatus(0);
                messageService.save(message);
                //即时通知作者
                wsService.sendMessCountToUser(post.getUserId());
            }
            //通知被艾特的人有人回复了你的文章
            if (content.startsWith("@")) {
                String username = content.substring(1, content.indexOf(" "));
                User user = userService.getOne(new QueryWrapper<User>()
                        .eq("username", username)
                );//根据用户名查到这个用户
                if (user != null) {//查到了就通知他！
                    UserMessage message = new UserMessage();
                    message.setPostId(jid);
                    message.setCommentId(comment.getUserId());
                    message.setFromUserId(getProfileId());
                    message.setToUserId(user.getId());//通知作者，也就是文章的发表者
                    message.setType(2);//0是系统消息，1是其他消息
                    message.setContent(content.substring(username.length() + 2));
                    message.setCreated(new Date());
                    message.setStatus(0);
                    messageService.save(message);
                    //即时通知被@的用户
                    wsService.sendMessCountToUser(comment.getUserId());
                }
            }
            return Result.success().action("/post/" + jid);
        } else {
            return Result.success("你操作的太快了,休息一下吧!");
        }
    }

    @ResponseBody
    @PostMapping("/post/jieda-delete/")
    public Result reply(Long id) {

        Assert.notNull(id, "评论id不能为空！");

        Comment comment = commentService.getById(id);

        Assert.notNull(comment, "找不到对应评论！");

        if (comment.getUserId().longValue() != getProfileId().longValue()) {
            return Result.fail("不是你发表的评论！");
        }
        commentService.removeById(id);

        // 评论数量减一
        Post post = postService.getById(comment.getPostId());
        post.setCommentCount(post.getCommentCount() - 1);
        postService.saveOrUpdate(post);

        //评论数量减一
        postService.incrCommentAndUnionForWeekRank(comment.getPostId(), false);

        return Result.success(null);
    }

}



